<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1.3. 正则表达式的其它改进（Other Regular Expression Changes）</title>
</head>
<body>
<!--
    正则表达式是在 JavaScript 中操作字符串的重要方式之一，和很多其它语言相似，
    它在最近的几个版本中并未发生太大的变化。
    不过，为了和针对字符串的修改一起作伴，ECMAScript 6 也给正则表达式做了一些改进。
-->

</body>
<script>
    //=============================1.3.1. 正则表达式的 y 标志（The Regular Expression y Flag）======================
    function regexTestOne() {
        /*
    粘滞模式（stickyPattern）

    ECMAScript 6 将 Firefox 对正则表达式拓展的私有 y 标志纳入了标准。
    y 标志涉及正则表达式与检索相关的 sticky 属性，
    它表示从正则表达式设置的 lastIndex 属性值的位置开始检索字符串中的匹配字符。
    如果以该位置为起点，之后没有相应的匹配，那么正则表达式将停止检索。
    为了展示它是如何工作的，考虑如下的代码：
     */
        var text = "hello1 hello2 hello3",
            pattern = /hello\d\s?/,
            result = pattern.exec(text),
            globalPattern = /hello\d\s?/g,
            globalResult = globalPattern.exec(text),
            stickyPattern = /hello\d\s?/y,
            stickyResult = stickyPattern.exec(text);

        console.log(result);
        console.log(globalResult);
        console.log(stickyResult);

        console.log(result[0]);         // "hello1 "
        console.log(globalResult[0]);   // "hello1 "
        console.log(stickyResult[0]);   // "hello1 "

        pattern.lastIndex = 1;
        globalPattern.lastIndex = 1;
        stickyPattern.lastIndex = 1;

        result = pattern.exec(text);
        globalResult = globalPattern.exec(text);
        stickyResult = stickyPattern.exec(text);

        console.log(result[0]);         // "hello1 "
        console.log(globalResult[0]);   // "hello2 "
        console.log(stickyResult[0]);   // Error! stickyResult is null
        /*
        在那之后，三种匹配模式的 lastIndex 属性全部更改为 1，意味着它们的匹配起始位置为第二个字符。
        无标志位的正则表达式会完全忽略掉 lastIndex 并像往常那样返回 "hello1 " 匹配。
        带有 g 标志位的正则表达式返回的匹配是 "hello2 "，因为它的搜索起点为第二个字符（"e"）。
        启用粘滞模式的正则表达式在第二个字符之后没有获得任何匹配，所以 stickyResult 为 null 。
         */

    }

    function regexTestTwo() {
        /*
            匹配操作一旦发生，带有粘滞标志位的匹配模式会保存上次匹配结果末尾的下一个字符的索引。
            如果一次匹配没有获得任何结果，那么 lastIndex 的值将重置为 0 。
            全局标志位的行为与其相同，如下所示：
         */
        var text = "hello1 hello2 hello3",
            pattern = /hello\d\s?/,
            result = pattern.exec(text),
            globalPattern = /hello\d\s?/g,
            globalResult = globalPattern.exec(text),
            stickyPattern = /hello\d\s?/y,
            stickyResult = stickyPattern.exec(text);

        console.log('text:', text);
        console.log('result = pattern.exec(text);result[0]:  >>>>', result[0]);         // "hello1 "
        console.log('globalResult = globalPattern.exec(text);globalResult[0]:  >>>>', globalResult[0]);   // "hello1 "
        console.log('stickyResult = stickyPattern.exec(text);stickyResult[0]:  >>>>', stickyResult[0]);   // "hello1 "

        console.group('-------------匹配结果的末尾索引lastIndex----------------');
        console.log('pattern.lastIndex:', pattern.lastIndex);         // 0
        console.log('globalPattern.lastIndex:', globalPattern.lastIndex);   // 7
        console.log('stickyPattern.lastIndex:', stickyPattern.lastIndex);   // 7
        console.groupEnd();

        result = pattern.exec(text);
        globalResult = globalPattern.exec(text);
        stickyResult = stickyPattern.exec(text);

        console.log(result[0]);         // "hello1 "
        console.log(globalResult[0]);   // "hello2 "
        console.log(stickyResult[0]);   // "hello2 "

        console.log(pattern.lastIndex);         // 0
        console.log(globalPattern.lastIndex);   // 14
        console.log(stickyPattern.lastIndex);   // 14
        /*
        首次和第二次调用 exec() 之后，stickyPattern 和 globalPattern 的 lastIndex 属性值均分别为 7 和 14 。
        关于粘滞标志位，有两处微妙的细节需要牢记：

        1.只有在正则表达式对象上（regular expression object）上调用方法 lastIndex 才会生效，例如 exec() 和 test()。
            如果将正则表达式传递给 match() 这样的字符串方法，粘滞行为则无法体现。
        2.当使用 ^ 字符来匹配字符串的首部时，粘滞正则表达式只会匹配整个字符串的首部位置（或多行模式下的行首）。
            如果 lastIndex 为 0，那么不论正则表达式是否带有粘滞标志位，^ 的表现均一致。
         */
    }

    function detectYexist() {
        console.group('---------------标志位y探测----------------');
        // 和其它正则表达式标志位相同，你可以根据属性来探测 y 是否存在。你可以如下检查 sticky 属性：
        var pattern = /hello\d/y;
        console.log('标志位y是否存在:',pattern.sticky);    // true
        console.groupEnd();
    }

    /*
    和 u 标志类似，y 标志同样是个语法变动，所以在旧的 JavaScript 引擎中它会造成语法错误。你可以使用下面的方式来检测：

    function hasRegExpY() {
        try {
            var pattern = new RegExp(".", "y");
            return true;
        } catch (ex) {
            return false;
        }
    }
    这段代码类似于 u 标志的检查，即如果不能使用 y 标志来创建正则表达式则返回 false 。同样，为了避免语法错误的发生，请确保在旧的 JavaScript 引擎中使用 RegExp 构造函数来定义使用 y 标志的正则表达式。
     */
    // TODO: 1.3.2. 正则表达式副本（Duplicating Regular Expressions）
    // TODO: 1.3.3. 标志位属性（The flags Property）


</script>
<script>
    // -------------------CLIENT----------------------
    //regexTestOne();
    regexTestTwo();
    detectYexist();
</script>
</html>